using System;
using System.Diagnostics;
using CodePlex.DnD4eCampaignManager.DnD4e;
using CodePlex.DnD4eCampaignManager.Services.Interfaces;

namespace CodePlex.DnD4eCampaignManager.Services
{
    public class DungeonsAndDragonsInsiderMonsterImporter : IDungeonsAndDragonsInsiderMonsterImporter
    {
        public Monster CreateMonsterFromHtmlString(string monsterText)
        {
            monsterText = monsterText.Replace(Environment.NewLine, string.Empty).Replace("> ", ">").Replace(" <", "<");
            Monster monster = new Monster(new Abilities(), new Defenses(), new HitPoints(), new Movement(), new Senses(), new Initiative());
            monster.Name = ParseName(monsterText, "Monster");
            monster.Level = 1;
            monster.InitiativeModifier = ReadFlavorInt(monsterText, "Initiative", 0);
            monster.DefenseArmorClass = ReadFlavorInt(monsterText, "AC", 10);
            monster.DefenseFortitude = ReadFlavorInt(monsterText, "Fortitude", 10);
            monster.DefenseReflex = ReadFlavorInt(monsterText, "Reflex", 10);
            monster.DefenseWillpower = ReadFlavorInt(monsterText, "Will", 10);
            monster.HitPointsMaximum = ReadFlavorInt(monsterText, "HP", 1);
            monster.SpecialQualities = string.Empty;
            monster.AttackPowers = string.Empty;
            monster.Tactics = string.Empty;
            monster.Conditions = string.Empty;
            monster.Elite = false;
            return monster;
        }

        public Monster ImportMonster(string monsterHtml)
        {
            try
            {
                return CreateMonsterFromHtmlString(monsterHtml);
            }
            catch ( Exception ex )
            {
                Debug.WriteLine(ex.Message);
                return null;
            }
        }

        private static string ParseName(string fileText, string defaultName)
        {
            string searchFor = "<span class=\"level\">";
            int pos = fileText.IndexOf(searchFor);
            if ( pos == -1 )
            {
                return defaultName;
            }

            string nameText = fileText.Substring(pos + searchFor.Length);

            // Parse off text before second span close tag
            searchFor = "</span>";
            pos = nameText.IndexOf(searchFor);
            pos = nameText.IndexOf(searchFor, pos + 1);
            if ( pos == -1 )
            {
                return defaultName;
            }

            nameText = nameText.Substring(pos + searchFor.Length);

            pos = nameText.IndexOf("<span");
            if ( pos == -1 )
            {
                return defaultName;
            }

            nameText = nameText.Substring(0, pos);

            nameText = nameText.Trim();

            return nameText;
        }

        private static int ReadFlavorInt(string fileText, string flavorText, int defaultValue)
        {
            /*
             <h1 class="monster"><span class="level">Level 1 Monster<span class="xp">XP 100</span></span>Ugly Monster<span class="type">Small natural humanoid</span></h1><p class="flavor"><b>Initiative</b>+1<b>HP</b>12;<b>Bloodied</b>6<br /><b>AC</b>13;<b>Fortitude</b>14,<b>Reflex</b>15,<b>Will</b>16<br /><b>Speed</b>6</p><b>Str</b>8 (-1)<b>Dex</b>16 (+3)<b>Wis</b>10 (0)<b>Con</b>11 (0)<b>Int</b>6 (-2)<b>Cha</b>15 (+2)</p>
             */
            string searchFor = "<b>" + flavorText + "</b>";
            int pos = fileText.IndexOf(searchFor);
            if ( pos == -1 )
            {
                return defaultValue;
            }

            string valueText = fileText.Substring(pos + searchFor.Length);

            // Look for the value
            string intStr = string.Empty;
            bool foundStr = false;
            for ( int i = 0; i < valueText.Length; ++i )
            {
                if ( Char.IsDigit(valueText[i]) )
                {
                    foundStr = true;
                    intStr += valueText[i];
                }
                else if ( foundStr )
                {
                    // We were adding the string text, and now we came to the end of it.
                    break;
                }
            }

            if ( intStr.Length == 0 )
            {
                // No value was found
                return defaultValue;
            }

            int result;
            if ( !Int32.TryParse(intStr, out result) )
            {
                return defaultValue;
            }

            return result;
        }
    }
}